/******************************
功能:打印一个变量在被加载到内存后从低地址到到高地址各bit的值
编码:UTF-8
Author:LysLee
******************************/

#include <stdio.h>

//声明一个结构体,该结构体恰好包含占满一个字节的8个位域
//在结构体中较先声明的元素一定存储在较低的地址, 所以这八个
//位域正好从低到高占满一个字节。
typedef struct {
    unsigned char bit0:1;
    unsigned char bit1:1;
    unsigned char bit2:1;
    unsigned char bit3:1;
    unsigned char bit4:1;
    unsigned char bit5:1;
    unsigned char bit6:1;
    unsigned char bit7:1;
} bit_struct;


#define bitprint(X) do { \
    int i; \
    bit_struct *b_s_point = (bit_struct*) &(X); \
    for(i=0;i<sizeof(X);i++) { \
        printf("%p\t%d %d %d %d %d %d %d %d\n", \
               b_s_point, \
               b_s_point->bit0, \
               b_s_point->bit1, \
               b_s_point->bit2, \
               b_s_point->bit3, \
               b_s_point->bit4, \
               b_s_point->bit5, \
               b_s_point->bit6, \
               b_s_point->bit7 \
        ); \
        b_s_point++;\
    }\
} while(0)


//***********测试代码***********
#ifdef BPDEBUG
int main()
{
    typedef struct {
        unsigned int i1:1;
        unsigned int i2:3;
        unsigned int i3:10; //对齐两字节
        unsigned int :2; 
            //无名位域占位，不可直接访问
            //因对齐可能会多于2个
        unsigned int i4:8;
    } BD; //bit domain struct
    BD bd= {0x1,0x6,0xb7,0xf1}; // 0xb7=10110111B
    puts("bd: {0x1,0x6,0xb7,0xf1}"); 
    puts("bits of fields in bd: ");
    puts("i1:1, i2:3, i3:10, pading:2, i4:8");
    printf("bd.i1: %#x, bd.i2:%#x, bd.i3: %#x, pading, bd.i4: %#x\n", 
           bd.i1,
           bd.i2,
           bd.i3,
           bd.i4);
    puts("bits map of bd:");
    bitprint(bd);
    typedef struct {
        unsigned  low_bit_pos:4;
  	    unsigned  high_bit_pos:4;    
    } BC; //bits char
    unsigned char uc = 0xf0; //M:f:1, L:0
    BC *bcp = (BC*)&uc;
    if(bcp->low_bit_pos == 0x0) { //L-->M
  	    printf("Bit Order: Little Endian(L-->M)\n");
    } else if (bcp->low_bit_pos == 0xf) { //M-->L 
  	    printf("Bit Order: Big Endian(M-->L)\n");
    }
    unsigned n = 0x0000ffff; //M:0, L:f:1
    unsigned char *ucp = (unsigned char *)&n;
    if(*ucp == 0x00) { //M-->L
  	    printf("Byte Order: Big Endian(M-->L)\n");
    } else if (*ucp == 0xff) { //L--> 
  	    printf("Byte Order: Little Endian(L-->M)\n");
    }
    return 0;
  
}

#endif // BPDEBUG
